package resource

import (
	"crypto/md5"
	"encoding/base64"
	"time"
)

func NewResourceSet() *ResourceSet {
	return &ResourceSet{
		Items: []*Resource{},
	}
}

func (s *ResourceSet) Add(item *Resource) {
	s.Items = append(s.Items, item)
}

func NewResource() *Resource {
	return &Resource{
		Meta:        NewMeta(),
		Spec:        NewSpec(),
		Cost:        NewCost(),
		Status:      NewStatus(),
		ContentHash: NewContentHash(),
	}
}

func (c *Resource) AddTag(tag *Tag) {
	c.Tags = append(c.Tags, tag)
}

func MustHash(data string) string {
	h := md5.New()
	_, err := h.Write([]byte(data))
	if err != nil {
		panic(err)
	}
	return base64.StdEncoding.EncodeToString(h.Sum(nil))
}

func (r *Resource) MakeContentHash() {
	ch := r.ContentHash
	ch.SpecHash = MustHash(r.Spec.String())
	if r.Cost != nil {
		ch.CostHash = MustHash(r.Cost.String())
	}
	if r.Status != nil {
		ch.StatusHash = MustHash(r.Status.String())
	}
}

func (r *Resource) HasTag() bool {
	return len(r.Tags) > 0
}

func NewMeta() *Meta {
	return &Meta{
		Extra: map[string]string{},
	}
}

// 自定义保存时的表名
func (m *Meta) TableName() string {
	return "resource_meta"
}

func NewSpec() *Spec {
	return &Spec{
		Extra: map[string]string{},
	}
}

// gorm 保存时
func (c *Spec) TableName() string {
	return "resource_spec"
}

func NewCost() *Cost {
	return &Cost{}
}

// gorm 保存时
func (c *Cost) TableName() string {
	return "resource_cost"
}

func NewStatus() *Status {
	return &Status{
		PublicAddress:  []string{},
		PrivateAddress: []string{},
	}
}

// gorm 保存时
func (c *Status) TableName() string {
	return "resource_status"
}

func NewContentHash() *ContentHash {
	return &ContentHash{}
}

func NewTag() *Tag {
	return &Tag{
		Extra: map[string]string{},
	}
}

func NewKVTag(p TAG_PURPOSE, key, value string) *Tag {
	return &Tag{
		UpdateAt: time.Now().Unix(),
		Purpose:  p,
		Key:      key,
		Value:    value,
		Extra:    map[string]string{},
	}
}

// gorm 保存时
func (c *Tag) TableName() string {
	return "resource_tag"
}
